package com.mlnx.ecg.ui.databuffer;

import com.alibaba.fastjson.JSON;
import com.mlnx.ecg.ui.config.ECGDeviceConstant;

import java.util.ArrayList;
import java.util.List;

public class RealEcgDatabuffer {

    private Integer sampling;// 采样率

    private Integer maxElements;// 最大保存点数量

    private List<Float[]> bufferList;// 心电数据

    private Integer writeIndex;// 数据写入下标

    private Integer readIndex;// 数据读取下标

    private Integer secondBuffer = 20;// 数据缓存时间

    private Integer loop;// 缓存池循环圈数

    public RealEcgDatabuffer() {
        sampling = 500;// 初始化默认采样率
        maxElements = sampling * secondBuffer;

        writeIndex = 0;
        readIndex = 0;

        loop = 0;

        // 初始化数据缓存列
        bufferList = new ArrayList<Float[]>();
        for (int index = 0; index < ECGDeviceConstant.ECGCHANNELNUM; index++) {
            Float[] tempFloatArray = new Float[maxElements];
            bufferList.add(tempFloatArray);
        }
    }

    // 输入心电数据
    private void inputEcgData(Float[] data) {
        for (int i = 0; i < ECGDeviceConstant.ECGCHANNELNUM; i++) {
            bufferList.get(i)[writeIndex] = data[i];
        }

        writeIndex++;

        if ((writeIndex + 1) >= maxElements) {
            writeIndex = 0;
            loop++;
        }
    }

    // 输出心电数据
    public List<Float[]> outputEcgData(Integer millisecond, boolean first,
                                       boolean auto) {
        Integer count = millisecond * sampling / 1000;// 每个导联所需画的点个数

        // 是否第一次绘制数据
        if (first) {
            if (auto)
                readIndex = writeIndex;
            else
                readIndex = writeIndex - count - sampling / 2;

            loop = 0;
            // if (readIndex < 0) {
            // readIndex += maxElements;
            // loop = 1;
            // } else {
            // loop = 0;
            // }
        }

        // 判断所需数据是否超过已写入数据
        Integer needIndex = readIndex + count;

        // System.out.println(needIndex + "--" + readIndex + "--" + (writeIndex
        // + (maxElements * loop)) + "--" + count);

        // 如果需要数据超出已写数据
        if (needIndex > writeIndex + (maxElements * loop) || count == 0) {
            return null;
        }

        // 如果数据储存速度过快
        if (writeIndex + (maxElements * loop) - needIndex > 1.5 * sampling) {
            count += sampling / 2;
        }

        List<Float[]> outputData = new ArrayList<Float[]>();


        for (int index = 0; index < ECGDeviceConstant.ECGCHANNELNUM; index++) {
            Float[] tempFloatArray = new Float[count];
            outputData.add(tempFloatArray);
        }

        for (int i = 0; i < count; i++) {
            for (int j = 0; j < ECGDeviceConstant.ECGCHANNELNUM; j++) {
                outputData.get(j)[i] = bufferList.get(j)[readIndex];
            }

            readIndex++;

            if ((readIndex + 1) >= maxElements) {
                readIndex = 0;
                loop--;
            }
        }

        return outputData;
    }

    public void inputEcgData(byte[] data) {
        byte[] eightChannelData = new byte[24];

        for (int i = 0; i < data.length - 24 + 1; ) {
            for (int j = 0; j < 24; j++) {
                eightChannelData[j] = data[i++];
            }

            inputEcgData(proData(eightChannelData, false));
        }
    }

    // 未加密数据
    private Float[] proData(byte[] decodedData, boolean original) {
        List<Integer> data8Channel = new ArrayList<Integer>();

        for (int i = 0; i < decodedData.length; ) {
            int value = 0;

            byte b = decodedData[i++];
            value |= (b & 0x000000ff);
            value <<= 8;

            b = (byte) decodedData[i++];
            // value |= ((b & 0x000000ff) << 8);
            value |= (b & 0x000000ff);
            value <<= 8;

            b = (byte) decodedData[i++];
            // value |= ((b & 0x000000ff) << 16);
            value |= (b & 0x000000ff);

            data8Channel.add(value);
        }

        // saveDataToFile(data8Channel);
        System.out.println(JSON.toJSONString(data8Channel));

        Float[] mvData = new Float[12];
        mvData[0] = (ad2mv(data8Channel.get(0), original));
        mvData[1] = (ad2mv(data8Channel.get(1), original));
        mvData[2] = (ad2mv(data8Channel.get(1), original) - ad2mv(
                data8Channel.get(0), original));
        mvData[3] = ((float) -0.5 * (ad2mv(data8Channel.get(1), original) + ad2mv(
                data8Channel.get(0), original)));
        mvData[4] = (ad2mv(data8Channel.get(0), original) - (float) 0.5
                * ad2mv(data8Channel.get(1), original));
        mvData[5] = (ad2mv(data8Channel.get(1), original) - (float) 0.5
                * ad2mv(data8Channel.get(0), original));
        mvData[6] = (ad2mv(data8Channel.get(2), original));
        mvData[7] = (ad2mv(data8Channel.get(3), original));
        mvData[8] = (ad2mv(data8Channel.get(4), original));
        mvData[9] = (ad2mv(data8Channel.get(5), original));
        mvData[10] = (ad2mv(data8Channel.get(6), original));
        mvData[11] = (ad2mv(data8Channel.get(7), original));

        return mvData;
    }

    // ad数据转换mv公式
    private float ad2mv(int value, boolean original) {
        if (original)
            return (float) ((value - 0x800000) * 0.476837 / 12f / 1000);

        return (float) ((value - 6000) / 820.0f);
    }

}
